package com.cf.spider;

import com.cf.spider.core.controller.JobInfoController;
import com.cf.spider.core.controller.JobTaskController;
import com.cf.spider.core.fetch.FetchJob;
import com.cf.spider.core.fetch.FetchService;
import com.cf.spider.core.model.service.JobInfoService;
import com.cf.spider.core.model.service.JobTaskService;
import com.cf.spider.core.push.PushResultListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * boot-awm-SpiderConfig
 *
 * @author <a href="2428922347@qq.com">Zhu mingming</a>
 * @info
 * @since 2018/7/11 上午 10:37
 */
@Slf4j
@Configuration
@EnableScheduling
@EnableConfigurationProperties(SpiderSystemProperty.class)
public class SpiderConfig implements InitializingBean {


    @Bean
    public JobInfoController jobInfoController() {
        log.info("实例化JobInfoController");
        return new JobInfoController();
    }

    @Bean
    public JobTaskController jobTaskController() {
        log.info("实例化JobTaskController");
        return new JobTaskController();
    }

    @Bean
    public JobTaskService jobTaskService() {
        log.info("实例化JobTaskService");
        return new JobTaskService();
    }

    @Bean
    public JobInfoService jobInfoService() {
        log.info("实例化JobInfoService");
        return new JobInfoService();
    }

    @Bean
    public FetchJob fetchJob() {
        log.info("实例化FetchJob");
        return new FetchJob();
    }

    @Bean
    public FetchService fetchService() {
        log.info("实例化FetchService");
        return new FetchService();
    }


    @Bean
    public Executor spiderTaskExecutor() {
        log.info("初始化抓取线程池！");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(5);
        //配置最大线程数
        executor.setMaxPoolSize(20);
        //配置队列大小
        executor.setQueueCapacity(500);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix("spider-fetch-");
        // rejection-policy：当pool已经达到max size的时候，如何处理新任务
        // CALLER_RUNS：不在新线程中执行任务，而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }

    //##################################redis-推送结果通知##########################
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter configUpdateListener) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(configUpdateListener, new PatternTopic("spider-push-result"));
        return container;
    }

    @Bean
    PushResultListener robSuccessListener() {
        log.info("实例化PushResultListener");
        return new PushResultListener();
    }


    @Bean
    MessageListenerAdapter configUpdateListener(PushResultListener receiver) {
        return new MessageListenerAdapter(receiver, "listen");
    }


    @Autowired
    private FreeMarkerProperties freeMarkerProperties;

    @Override
    public void afterPropertiesSet() throws Exception {
        String[] templateLoaderPath = freeMarkerProperties.getTemplateLoaderPath();
        ArrayList<String> paths = new ArrayList();
        paths.addAll(Arrays.asList(templateLoaderPath));
        paths.add("classpath:/template-spider/");
        String[] strings = paths.toArray(new String[paths.size()]);
        freeMarkerProperties.setTemplateLoaderPath(strings);
    }
}
